package com.ccys.doctor.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.ccys.common.third.aws.s3.S3Util;
import com.ccys.common.third.pubnub.Message;
import com.ccys.common.third.pubnub.PubNubHelper;
import com.ccys.common.util.Kit;
import com.ccys.common.vo.ResponseResultApp;
import com.ccys.db.cache.UserUtil;
import com.ccys.db.dto.doctor.constant.PubnubConstant;
import com.ccys.db.dto.doctor.consultStage.GetMasterDataOfSpecificConsultationDto;
import com.ccys.db.dto.doctor.consultStage.UploadTextBasedFilesDto;
import com.ccys.db.mapper.TblBookingSummaryMapper;
import com.ccys.db.mapper.TblCountryMapper;
import com.ccys.db.mapper.TblSymptomMapper;
import com.ccys.db.vo.doctor.consultStage.GetMasterDataVo;
import com.ccys.db.vo.doctor.consultStage.GetTBTCConsultingPatientVo;
import com.ccys.doctor.service.ConsultStageService;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author：XLY
 * @Date：2024/2/28 0028
 */
@Service
@Slf4j
public class ConsultStageServiceImpl implements ConsultStageService {


    @Resource
    private TblSymptomMapper symptomMapper;

    @Resource
    private TblBookingSummaryMapper summaryMapper;

    @Resource
    private TblCountryMapper countryMapper;

    @Resource
    private PubNubHelper pubNubHelper;

    @Override
    public GetMasterDataVo getMasterData() {
        GetMasterDataVo vo = new GetMasterDataVo();
        //hotline
        //Whc_hotline
        String whc_hotline = symptomMapper.getSysValue("Whc_hotline");
        vo.setHotline(whc_hotline);
        //verified_otp_code
        String verified_otp_code = symptomMapper.getSysValue("verified_otp_code");
        vo.setVerifiedOtpCode(verified_otp_code);
        //GST_Reg_No
        String gst_reg_no = symptomMapper.getSysValue("GST_Reg_No");
        vo.setGstRegNo(gst_reg_no);
        //consultant_fee
        // TODO: 2024/2/28 0028 consultant_fee
        //获取consultation_fee
        //获取timeOutSkipBooking
        String time_out_skip_booking = symptomMapper.getSysValue("Time_Out_Skip_Booking");
        vo.setTimeOutSkipBooking(time_out_skip_booking);

        //获取timeOutCancelBooking
        String time_out_cancel_booking = symptomMapper.getSysValue("Time_Out_Cancel_Booking");
        vo.setTimeOutCancelBooking(time_out_cancel_booking);

        //获取flagPatient
        List<GetMasterDataVo.BaseVo> flagPatient = symptomMapper.getFlagPatient();
        vo.setFlagPatients(flagPatient);

        vo.setPubnubPubkey(PubnubConstant.PUBNUB_PUBKEY);
        vo.setPubnubSubkey(PubnubConstant.PUBNUB_SUBKEY);
        //获取AutomatedGreetingTbtc
        String textbased_automated_greeting_tbtc = symptomMapper.getSysValue("Textbased_Automated_Greeting_Tbtc");
        vo.setAutomatedGreetingTbtc(textbased_automated_greeting_tbtc);


        //获取symptoms
        List<GetMasterDataVo.BaseVo> masterSymptoms = symptomMapper.getMasterSymptoms();
        vo.setSymptoms(masterSymptoms);
        //获取duration_unit
        List<GetMasterDataVo.DurationUnitVo> durationUnit = symptomMapper.getDurationUnit();
        vo.setDurationUnit(durationUnit);

        //获取specialisation_type
        List<GetMasterDataVo.BaseVo> specialisationType = symptomMapper.getSpecialisationType();
        vo.setSpecialisationType(specialisationType);

        //获取diagnosis
        List<GetMasterDataVo.DiagnosisVo> diagnosis = symptomMapper.getDiagnosis();
        vo.setDiagnosis(diagnosis);

        //获取medication_reactions
        List<GetMasterDataVo.BaseVo> medicationReaction = symptomMapper.getMedicationReaction();
        vo.setMedicationReactions(medicationReaction);

        //获取usage_period
        List<GetMasterDataVo.BaseVo> medicationUsagePeriod = symptomMapper.getMedicationUsagePeriod();
        vo.setMedicationUsagePeriods(medicationUsagePeriod);

        //获取company_name_specialisation
        List<String> companyNameSpecialisation = symptomMapper.getCompanyNameSpecialisation();
        vo.setCompanyNameSpecialisation(companyNameSpecialisation);

        //获取Master_company_name
        List<String> masterCompanyName = symptomMapper.getMasterCompanyName();
        vo.setMasterCompanyName(masterCompanyName);
        return vo;
    }

    @Override
    public GetMasterDataVo getMasterDataOfSpecificConsultation(GetMasterDataOfSpecificConsultationDto dto) {
        GetMasterDataVo vo = new GetMasterDataVo();
        //Whc_hotline
        String whc_hotline = symptomMapper.getSysValue("Whc_hotline");
        vo.setHotline(whc_hotline);
        //GST_Reg_No
        String gst_reg_no = symptomMapper.getSysValue("GST_Reg_No");
        vo.setGstRegNo(gst_reg_no);
        //consultant_fee
        // TODO: 2024/2/28 0028 consultant_fee

        Integer masterDataType = dto.getMasterDataType();
        masterDataType = Objects.nonNull(masterDataType) ? masterDataType : 0;
        //只有all和textbase特殊一点
        switch (masterDataType) {
            case 1:
                //Diagnosis,
                //获取diagnosis
                List<GetMasterDataVo.DiagnosisVo> diagnosis = symptomMapper.getDiagnosis();
                vo.setDiagnosis(diagnosis);
                break;
            case 2:
                //CompanySpecialisation
                //获取company_name_specialisation
                List<String> companyNameSpecialisation = symptomMapper.getCompanyNameSpecialisation();
                vo.setCompanyNameSpecialisation(companyNameSpecialisation);
                break;
            case 3:
                //MasterCompanyName
                //获取Master_company_name
                List<String> masterCompanyName = symptomMapper.getMasterCompanyName();
                vo.setMasterCompanyName(masterCompanyName);
                break;
            case 4:
                //Symptoms
                //获取symptoms
                List<GetMasterDataVo.BaseVo> masterSymptoms = symptomMapper.getMasterSymptoms();
                vo.setSymptoms(masterSymptoms);
                break;
            case 5:
                //FlagPatients
                //获取flagPatient
                List<GetMasterDataVo.BaseVo> flagPatient = symptomMapper.getFlagPatient();
                vo.setFlagPatients(flagPatient);
                break;
            case 6:
                //DurationUnit
                //获取duration_unit
                List<GetMasterDataVo.DurationUnitVo> durationUnit = symptomMapper.getDurationUnit();
                vo.setDurationUnit(durationUnit);
                break;
            case 7:
                //SpecialisationType
                //获取specialisation_type
                List<GetMasterDataVo.BaseVo> specialisationType = symptomMapper.getSpecialisationType();
                vo.setSpecialisationType(specialisationType);
                break;
            case 8:
                //MedicationReactions
                //获取medication_reactions
                List<GetMasterDataVo.BaseVo> medicationReaction = symptomMapper.getMedicationReaction();
                vo.setMedicationReactions(medicationReaction);
                break;
            case 9:
                //MedicationUusagePeriods
                //获取usage_period
                List<GetMasterDataVo.BaseVo> medicationUsagePeriod = symptomMapper.getMedicationUsagePeriod();
                vo.setMedicationUsagePeriods(medicationUsagePeriod);
                break;
            default:
                //All,
                //TextBase
                vo = getMasterData();
                break;
        }
        return vo;
    }

    @Override
    public ResponseResultApp getTBTCConsultingOrIncomingPatient(String timeslot, String type) {

        String doctorId = UserUtil.getCurLoginUserId();
        List<GetTBTCConsultingPatientVo.BookingVo> bookings = summaryMapper.getTBTCConsultingPatient(doctorId, timeslot, type);
        GetTBTCConsultingPatientVo vo = new GetTBTCConsultingPatientVo();
        vo.setBookingList(bookings);
        String value = symptomMapper.getSysValue("Textbased_Appointments_Minute_Timeslot");
        vo.setTbtcTimeslot(Integer.parseInt(value));
        vo.setType(type);
        List<String> dateList = bookings.stream().filter(x -> Objects.nonNull(x.getAppointmentTime())).map(x -> {
            Date appointmentTime = x.getAppointmentTime();
            String format = DateUtil.format(appointmentTime, "MM/dd/yyyy");
            return format;
        }).collect(Collectors.toList());
        vo.setDateList(dateList);
        return ResponseResultApp.success(vo);
    }

    /**
     * 按照源码处理createdOnDisplay这个字段
     *
     * @param createdOn createdOn
     * @return createdOnDisplay
     */
    @Override
    public String prepareCreatedOnDisplay(Date createdOn) {
        String finalReturn = null;
        if (createdOn != null) {
            long nMinutes = DateUtil.between(createdOn, new Date(), DateUnit.MINUTE);
            if (nMinutes == 0) {
                finalReturn = "Just now";
            } else if (nMinutes == 1) {
                finalReturn = "1 minute ago";
            } else if (nMinutes < 60) {
                finalReturn = nMinutes + " minutes ago";
            } else if (nMinutes >= 60 && nMinutes <= 120) {
                long nHours = nMinutes / 60;
                finalReturn = "about " + nHours + " hour ago";
            } else if (nMinutes > 120 && nMinutes <= 1440) {
                long nHours = nMinutes / 60;
                finalReturn = "about " + nHours + " hours ago";
            } else if (nMinutes > 1440 && nMinutes <= 2880) {
                finalReturn = "Yesterday";
            } else if (nMinutes > 2880 && nMinutes <= 86400) {
                long nDays = nMinutes / 1440;
                finalReturn = "about " + nDays + " days ago";
            } else if (nMinutes > 86400 && nMinutes <= 1036800) {
                long nMonths = nMinutes / 43200;
                finalReturn = "about " + nMonths + " months ago";
            } else {
                long nYears = nMinutes / 518400;
                finalReturn = "about " + nYears + " years ago";
            }
        }

        return finalReturn != null ? finalReturn : "";
    }

    @Override
    public Date getDoctorCountryTimeZone(String doctorId) {

        if (StringUtils.isNotEmpty(doctorId)) {
            Integer timezone = countryMapper.getTimezoneByDoctorId(doctorId);
            if (Objects.nonNull(timezone)) {
                // 获取当前的UTC时间
                Instant utcInstant = Instant.now();
                // 将UTC时间转换为Date格式
                Date utcDate = Date.from(utcInstant);
                Date timeByTimeZone = Kit.getTimeByTimeZone(utcDate, timezone);
                return timeByTimeZone;
            }
        }
        //新加坡时区和中国一致
        return new Date();
    }

    @Override
    public ResponseResultApp uploadTextBasedFiles(String param, Map<String, MultipartFile> fileMap) {
        UploadTextBasedFilesDto dto = JSONObject.parseObject(param, UploadTextBasedFilesDto.class);
        if (Objects.nonNull(dto)) {
            String bookingId = dto.getBookingId();
            List<UploadTextBasedFilesDto.FileVo> files = dto.getFiles();
            if (CollectionUtils.isNotEmpty(files)) {
                for (int i = 0; i < files.size(); i++) {
                    UploadTextBasedFilesDto.FileVo x = files.get(i);
                    MultipartFile file = fileMap.get(x.getId());
                    String originalFilename = file.getOriginalFilename();
                    if (originalFilename != null) {
                        int dotIndex = originalFilename.lastIndexOf(".");
                        if (dotIndex >= 0 && dotIndex < originalFilename.length() - 1) {
                            String extensionName = originalFilename.substring(dotIndex).toLowerCase();
                            //上传文件到s3
                            //文件夹是：LogPubNub/bookingId
                            //log-pubnub-0603202401561933285.jpg
                            //imageName的规则是log-pubnub - 时间戳5个随机数字字符 + 文件格式扩展名
                            String directoryName = "LogPubNub/" + bookingId + "/";
                            String fileName = "log-pubnub-" + System.currentTimeMillis() + RandomUtil.randomNumbers(5) + extensionName;
                            String objectKey = directoryName + fileName;
                            try {
                                String url = S3Util.putS3ObjectByInputStream("", objectKey, file.getInputStream());
                                //组装fileInfo
                                Message.File messageFile = new Message.File();
                                messageFile.setId(x.getId());
                                messageFile.setName(originalFilename);
                                messageFile.setName_s3(objectKey);
                                messageFile.setHeight(x.getHeight());
                                messageFile.setWidth(x.getWidth());
                                messageFile.set_mood_log(false);
                                messageFile.setUrl(url);
                                //创建缩略图 。。。
                                /**
                                 * {
                                 *     "content": null,
                                 *     "type": "file",
                                 *     "file": {
                                 *         "name_s3": "log-pubnub-0603202401561933285.jpg",
                                 *         "name": "win10壁纸.jpg",
                                 *         "url": "https://s3-ap-southeast-1.amazonaws.com/prv.staging.whitecoat.global/LogPubNub/8eff35ae-4b95-497b-9695-b293a70bc36d/log-pubnub-0603202401561933285.jpg",
                                 *         "is_mood_log": false,
                                 *         "height": 576,
                                 *         "width": 1024,
                                 *         "url_thumb": "https://s3-ap-southeast-1.amazonaws.com/prv.staging.whitecoat.global/LogPubNub/8eff35ae-4b95-497b-9695-b293a70bc36d/log-pubnub-thumb-0603202401561938111.jpg",
                                 *         "id": "8ad2348c-281f-48ba-8ff2-769e27aa618d"
                                 *     }
                                 * }
                                 */
                                boolean flag = isValidImageFormat(extensionName);
                                if (flag) {
                                    String extensionNameWithOutDot = extensionName.substring(1);
                                    ByteArrayOutputStream thumbOS = new ByteArrayOutputStream();
                                    Thumbnails.of(file.getInputStream())
                                            .size(500, 500)
                                            .outputFormat(extensionNameWithOutDot)
                                            .toOutputStream(thumbOS);
                                    //上传到s3
                                    String thumbFileName = "log-pubnub-thumb-" + System.currentTimeMillis() + RandomUtil.randomNumbers(5) + extensionName;
                                    String thumbObjectKey = directoryName + thumbFileName;
                                    String thumbUrl = S3Util.putS3ObjectByByte("", thumbObjectKey, thumbOS.toByteArray());
                                    messageFile.setUrl_thumb(thumbUrl);
                                } else {
                                    messageFile.setUrl_thumb(url);
                                }
                                //生成uuid,规则是: 病人？patient:doctor+"_"+account_id.toLowerCase()
                                String uuid = "doctor_"+UserUtil.getCurLoginUserId().toLowerCase();
                                //组装消息体
                                Message.MessageContent messageContent = new Message.MessageContent();
                                messageContent.setType("file");
                                messageContent.setFile(messageFile);
                                messageContent.setContent("");
                                //用pubnub推送这条消息
                                pubNubHelper.publish(uuid,bookingId,messageContent);
                                //pubnub取消订阅
                            } catch (IOException e) {
                                log.error(e.getMessage());
                            }
                        }
                    }
                }
            }
        }

        return ResponseResultApp.success();
    }


    /**
     * 判断文件后缀名属于图片
     *
     * @param ex 文件扩展名
     * @return
     */
    public boolean isValidImageFormat(String ex) {
        String[] allowedFormats = {".jpg", ".png", ".bmp", ".gif", ".jpeg", ".tiff"};

        for (String format : allowedFormats) {
            if (ex.equalsIgnoreCase(format)) {
                return true;
            }
        }

        return false;
    }


}
